package com.example.search.model;

import java.io.Serializable;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * 分页类
 */
public class Page<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 默认开始行
     */
    public static int DEFAULT_START = 1;
    /**
     * 默认每页显示行数
     */
    public static int DEFAULT_LIMIT = 20;
    /**
     * 默认页
     */
    public static int DEFAULT_PAGE = 1;

    private int pageNum;
    private int pageSize;
    private int startRow;
    private int endRow;
    private long total;
    private int pages;
    private boolean count;
    private Boolean reasonable;
    private Boolean pageSizeZero;
    private String countColumn;
    private String orderBy;
    private boolean orderByOnly;

    /**
     * 查询条件
     */
    private Map<String, Object> termQueryMap;
    /**
     * 查询条件
     */
    private Map<String, Object[]> rangeQueryMap;
    /**
     * 排序条件
     */
    private Map<String, String> sortMap;
    /**
     * 查询结果
     */
    private List<T> result = Collections.emptyList();

    @SuppressWarnings("static-access")
    public Page() {
        //默认开始行
        this.startRow = DEFAULT_START;
        //默认每页显示行数
        this.pageSize = DEFAULT_LIMIT;
        //默认页
        this.pageNum = DEFAULT_PAGE;
    }

    public Page(int start, int pageSize) {
        this.startRow = start;
        this.pageSize = pageSize;
        this.endRow = start == 1? 10: start + pageSize - 1;
        this.pageNum = DEFAULT_PAGE;
    }

    public int getStartRow() {
        if (this.startRow < 1) {
            this.startRow = DEFAULT_START;
        } else if (this.startRow > this.total) {
            if ((int)total % this.pageSize == 0) {
                this.startRow = (int)this.total / this.pageSize * this.pageSize;
            } else {
                this.startRow = (int)this.total / this.pageSize * this.pageSize + 1;
            }
        }
        return startRow;
    }

    public int getEndRow() {
        if (this.pageSize > 0 && this.pageNum > 0) {
            if (this.total == 1) {
                this.endRow = 1;
            } else if (this.total > 1) {
                if (this.pageSize >= this.total) {
                    this.endRow = (int) this.total;
                } else {
                    this.endRow = this.pageSize + this.getStartRow() - 1;
                }
                this.endRow = (this.endRow >= (int)this.total)? (int)this.total: this.endRow;
            }
        }
        return endRow;
    }


    public int getPageNum() {
        if (this.getStartRow() < this.pageSize) {
            this.pageNum = 1;
        } else {
            int step = 2;
            for (int i = 1 + this.pageSize; i <= this.total; i = i + this.pageSize) {
                if (this.getStartRow() == i) {
                    this.pageNum = step;
                    break;
                }
                if (this.getStartRow() >= this.total) {
                    this.pageNum = this.pages;
                    break;
                }
                step++;
            }
        }
        return pageNum;
    }

    public void setPageNum(int pageNum) {
        this.pageNum = pageNum;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public void setStartRow(int startRow) {
        this.startRow = startRow;
    }

    public void setEndRow(int endRow) {
        this.endRow = endRow;
    }

    public long getTotal() {
        return total;
    }

    public void setTotal(long total) {
        if (total > 0) {
            this.pageSize = (this.pageSize > 0)?this.pageSize : DEFAULT_LIMIT;
            if (this.startRow > total) {
                if ((int)total % this.pageSize == 0) {
                    this.startRow = (int)total / this.pageSize * this.pageSize;
                } else {
                    this.startRow = (int)total / this.pageSize * this.pageSize + 1;
                }
            }
            this.endRow = this.startRow + this.pageSize - 1;
            this.endRow = this.endRow > (int)total? (int)total: this.endRow;
            if ((int)total % this.pageSize == 0) {
                this.pages = (int)total / this.pageSize;
            } else {
                this.pages = (int)total / this.pageSize + 1;
            }
        }
        this.total = total;
    }

    public int getPages() {
        return pages;
    }

    public void setPages(int pages) {
        this.pages = pages;
    }

    public boolean isCount() {
        return count;
    }

    public void setCount(boolean count) {
        this.count = count;
    }

    public Boolean getReasonable() {
        return reasonable;
    }

    public void setReasonable(Boolean reasonable) {
        this.reasonable = reasonable;
    }

    public Boolean getPageSizeZero() {
        return pageSizeZero;
    }

    public void setPageSizeZero(Boolean pageSizeZero) {
        this.pageSizeZero = pageSizeZero;
    }

    public String getCountColumn() {
        return countColumn;
    }

    public void setCountColumn(String countColumn) {
        this.countColumn = countColumn;
    }

    public String getOrderBy() {
        return orderBy;
    }

    public void setOrderBy(String orderBy) {
        this.orderBy = orderBy;
    }

    public boolean isOrderByOnly() {
        return orderByOnly;
    }

    public void setOrderByOnly(boolean orderByOnly) {
        this.orderByOnly = orderByOnly;
    }

    public List<T> getResult() {
        return result;
    }

    public void setResult(List<T> result) {
        this.result = result;
    }

    public Map<String, String> getSortMap() {
        return sortMap;
    }

    public void setSortMap(Map<String, String> sortMap) {
        this.sortMap = sortMap;
    }

    public Map<String, Object> getTermQueryMap() {
        return termQueryMap;
    }

    public void setTermQueryMap(Map<String, Object> termQueryMap) {
        this.termQueryMap = termQueryMap;
    }

    public Map<String, Object[]> getRangeQueryMap() {
        return rangeQueryMap;
    }

    public void setRangeQueryMap(Map<String, Object[]> rangeQueryMap) {
        this.rangeQueryMap = rangeQueryMap;
    }

    @Override
    public String toString() {
        return "Page{" +
                "pageNum=" + this.getPageNum() +
                ", pageSize=" + pageSize +
                ", startRow=" + this.getStartRow() +
                ", endRow=" + this.getEndRow() +
                ", total=" + total +
                ", pages=" + pages +
                ", count=" + count +
                ", reasonable=" + reasonable +
                ", pageSizeZero=" + pageSizeZero +
                ", countColumn='" + countColumn + '\'' +
                ", orderBy='" + orderBy + '\'' +
                ", orderByOnly=" + orderByOnly +
                ", termQueryMap=" + termQueryMap +
                ", rangeQueryMap=" + rangeQueryMap +
                ", sortMap=" + sortMap +
                ", result=" + result +
                '}';
    }
}
